﻿using System;
using System.Collections.Generic;
using System.Linq;
using GitSharp;
using GitSharp.Core.RevPlot;

namespace GitCapture
{
    /// <summary>
    /// git仓库信息reader
    /// </summary>
    public class GitReader
    {
        private Repository _repository;

        #region

        private bool _isLoad;

        /// <summary>
        /// 是否已经加载
        /// </summary>
        public bool IsLoad
        {
            get { return _isLoad; }
        }
        /// <summary>
        /// 目录
        /// </summary>
        public string Dir
        {
            get
            {
                return !IsLoad
                    ? string.Empty
                    : _repository.Directory.Substring(0, _repository.Directory.LastIndexOf('.'));
            }
        }


        #endregion

        #region public method

        /// <summary>
        /// 根据路径加载git仓库信息
        /// </summary>
        /// <param name="path">仓库路径</param>
        public void Load(string path)
        {
            try
            {

                _repository = new Repository(path);
                _isLoad = true;
            }
            catch
            {
                _isLoad = false;
                throw;
            }
        }

        /// <summary>
        /// 关闭
        /// </summary>
        public void Close()
        {
            _repository.Close();
            _repository.Dispose();
            _isLoad = false;
        }

        /// <summary>
        /// 获取提交列表
        /// </summary>
        /// <param name="startCommitName">从该次提取开始取,提交名(标识 hash)</param>
        /// <returns></returns>
        public IEnumerable<Commit> GetCommitList(string startCommitName = null)
        {
            var plotCommitList = new PlotCommitList();
            var plotWalk = new PlotWalk(_repository);
            plotWalk.markStart(
                ((GitSharp.Core.Repository)_repository).getAllRefsByPeeledObjectId()
                    .Keys.Select(plotWalk.parseCommit));
            plotCommitList.Source(plotWalk);
            plotCommitList.fillTo(1000);
            var matchStartCommit = false;
            foreach (var plotCommit in plotCommitList)
            {
                if (matchStartCommit)
                    break;

                matchStartCommit = !string.IsNullOrWhiteSpace(startCommitName)
                                   && startCommitName.Equals(plotCommit.Name, StringComparison.OrdinalIgnoreCase);

                yield return _repository.Get<Commit>(plotCommit.Name);
            }
        }

        /// <summary>
        /// 获取提交信息
        /// </summary>
        /// <param name="name">提交名(标识 hash)</param>
        /// <returns></returns>
        public Commit GetCommit(string name)
        {
            return _repository.Get<Commit>(name);
        }

        /// <summary>
        /// 获取有修改的文件列表
        /// </summary>
        /// <param name="startCommitName">从该次提取开始取,提交名(标识 hash)</param>
        /// <returns></returns>
        public List<string> GetChangeFileList(string startCommitName = null)
        {
            var changedFiles = new List<string>();
            foreach (var commit in GetCommitList(startCommitName))
            {
                foreach (var change in commit.Changes.Where(m => !changedFiles.Contains(m.Path)
                    && !(new[] { ChangeType.Deleted, ChangeType.Renamed }).Contains(m.ChangeType)))
                {
                    changedFiles.Add(change.Path);
                }

            }
            return changedFiles;
        }

        #endregion
    }
}